/**
 * @file    goodwe_can.c
 * @brief   逆变器协议-固德威-CAN通信接口V6.0
 * @author  Liuwei
 * @version 1.0.1
 * @date    2023-04-30
 * 
 * @copyright Copyright (c) 2023 JBD-Energy Storage Technology Co. LTD
 * 
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version   <th>Author   <th>Description
 * <tr><td>2023-04-30 <td>1.0.1     <td>Liuwei   <td>首次创建
 * </table>
 */

/* includes ------------------------------------------------------------------*/
#include "goodwe_can.h"
#include "If_can.h"
#include "var_mng.h"
#include "param_mng.h"
#include "cfg_prj.h"
#include "parallel.h"
/* macro/define --------------------------------------------------------------*/

/* typedef -------------------------------------------------------------------*/
typedef struct 
{
    uint16_t can_id;      /* !< 报文ID */
    uint16_t send_cycle; /* !< 发送周期 */
    uint16_t send_cnt;   /* !< 计时器 */
    void(*pfunc_get_frame_msg)(can_frame_type *);
}send_frame_type;

typedef union 
{
    uint16_t half_word;
    struct 
    {
        uint16_t rsd1 : 1;
        uint16_t ov : 1;
        uint16_t uv : 1;
        uint16_t ot : 1;
        uint16_t ut : 1;
        uint16_t rsd5 : 1;
		uint16_t rsd6 : 1;
        uint16_t ocd : 1;
		
        uint16_t occ  : 1;
        uint16_t rsd9 : 1;
        uint16_t rsd10 : 1;
        uint16_t sys_err : 1;
        uint16_t cell_blc : 1;
        uint16_t rsd13 : 1;
		uint16_t rsd14 : 1;
        uint16_t rsd15 : 1;
	}name;
}alarm_msg_type;

typedef union
{
	uint8_t byte_data;
	struct
	{
		uint8_t rsd : 4;
		uint8_t force2_chg : 1;
		uint8_t force1_chg : 1;
		uint8_t dsg_en : 1;
		uint8_t chg_en : 1;
	}name;
}ask_cmd_type;
/* local functions -----------------------------------------------------------*/
static void can_get_0x351_msg(can_frame_type *can_msg);
static void can_get_0x355_msg(can_frame_type *can_msg);
static void can_get_0x356_msg(can_frame_type *can_msg);
static void can_get_0x359_msg(can_frame_type *can_msg);
static void can_get_0x35C_msg(can_frame_type *can_msg);
static void can_get_0x370_msg(can_frame_type *can_msg);
static void can_get_0x371_msg(can_frame_type *can_msg);
static void can_get_0x380_msg(can_frame_type *can_msg);
static void can_get_0x381_msg(can_frame_type *can_msg);
/* static variables ----------------------------------------------------------*/
static send_frame_type send_frame_list[] = 
{
    {0x351 , 1000 , 0 ,can_get_0x351_msg },
    {0x355 , 1000 , 0 ,can_get_0x355_msg },
    {0x356 , 1000 , 0 ,can_get_0x356_msg },
    {0x359 , 1000 , 0 ,can_get_0x359_msg },
    {0x35C , 1000 , 0 ,can_get_0x35C_msg },
    {0x370 , 1000 , 0 ,can_get_0x370_msg },
    {0x371 , 1000 , 0 ,can_get_0x371_msg },
    {0x380 , 1000 , 0 ,can_get_0x380_msg },
    {0x381 , 1000 , 0 ,can_get_0x381_msg },
};

#define CAN_LIST_NUM     (sizeof(send_frame_list)/sizeof(send_frame_type))
/* global variables ----------------------------------------------------------*/

/** ------------------------------------------------------------------------- *
  *                             Global function
 ** ------------------------------------------------------------------------- */
/**
 * @brief  获取需要发送的数据信息
 * @param  cycle
 * @param  can_buf
 * @return uint8_t 
 */
uint8_t goodwe_can_get_msg(uint32_t cycle , can_frame_type *can_buf)
{
    uint8_t i = 0;
    uint8_t msg_num = 0;

    for( i = 0; i < CAN_LIST_NUM; ++ i)
    {
        send_frame_list[i].send_cnt += cycle;
        if(send_frame_list[i].send_cnt >= send_frame_list[i].send_cycle)
        {
            send_frame_list[i].send_cnt = 0;
            send_frame_list[i].pfunc_get_frame_msg(&can_buf[msg_num ++]); 
        }
    }

    return msg_num;
}

/** ------------------------------------------------------------------------- *
  *                              Local function
 ** ------------------------------------------------------------------------- */
static void can_get_0x351_msg(can_frame_type *can_msg)
{
    can_msg->frame_type = CAN_FRAME_DATA;
    can_msg->id_type = CAN_ID_STD;
    can_msg->dlc = 8;
    can_msg->id = 0x351;

    can_msg->data.half_buf[0] = var_get_data(VAR_ID_TP_SOP_CV);
    can_msg->data.half_buf[1] = var_get_data(VAR_ID_TP_SOP_CC);
    can_msg->data.half_buf[2] = var_get_data(VAR_ID_TP_SOP_DC); 
    can_msg->data.half_buf[3] = var_get_data(VAR_ID_TP_SOP_DV);
}

static void can_get_0x355_msg(can_frame_type *can_msg)
{
	uint8_t soh  = 0;
    can_msg->frame_type = CAN_FRAME_DATA;
    can_msg->id_type = CAN_ID_STD;
    can_msg->dlc = 8;
    can_msg->id = 0x355;

    can_msg->data.half_buf[0] = var_get_data(VAR_ID_TP_SOC);
	soh = var_get_data(VAR_ID_TP_SOH);
	if(soh > 100)
		soh = 100;
    can_msg->data.half_buf[1] = soh;
    can_msg->data.half_buf[2] = 0;
    can_msg->data.half_buf[3] = 0;
}

static void can_get_0x356_msg(can_frame_type *can_msg)
{
    int32_t temp = 0;
	int16_t curr = 0;
	
    can_msg->frame_type = CAN_FRAME_DATA;
    can_msg->id_type = CAN_ID_STD;
    can_msg->dlc = 8;
    can_msg->id = 0x356;
    can_msg->data.half_buf[0] = var_get_data(VAR_ID_TP_VOLT);
    temp = (var_get_data(VAR_ID_TP_CURR_H) << 16) + var_get_data(VAR_ID_TP_CURR_L);
    curr = temp * 0.1;
    can_msg->data.half_buf[1] = (uint16_t)curr;
    can_msg->data.half_buf[2] = var_get_data(VAR_ID_TP_AVG_TEMP) - 2731;
    can_msg->data.half_buf[3] = 0;
}

extern master_data_type master_data_reg;
static void can_get_0x359_msg(can_frame_type *can_msg)
{
    alarm_msg_type alarm_msg = {0};
    alarm_msg_type warn_msg = {0};

    can_msg->frame_type = CAN_FRAME_DATA;
    can_msg->id_type = CAN_ID_STD;
    can_msg->dlc = 8;
    can_msg->id = 0x359;

	alarm_msg.name.occ = master_data_reg.total_prp_msg.bit.occ | master_data_reg.total_prp_msg.bit.occ2;
	alarm_msg.name.ocd = master_data_reg.total_prp_msg.bit.ocd;
	
	alarm_msg.name.ot = master_data_reg.total_prp_msg.bit.otc | master_data_reg.total_prp_msg.bit.otd | 
						master_data_reg.total_prp_msg.bit.otm | master_data_reg.total_prp_msg.bit.ote;
	alarm_msg.name.ut = master_data_reg.total_prp_msg.bit.utc | master_data_reg.total_prp_msg.bit.utd |
						master_data_reg.total_prp_msg.bit.ute ;
	alarm_msg.name.sys_err = master_data_reg.total_prp_msg.bit.sc | master_data_reg.total_prp_msg.bit.fcmos |
	                         master_data_reg.total_prp_msg.bit.fdmos |master_data_reg.total_prp_msg.bit.afe_err |
	                         master_data_reg.total_prp_msg.bit.col | master_data_reg.total_prp_msg.bit.tol;
//	alarm_msg.name.ov = master_data_reg.total_prp_msg.bit.cov;
//	alarm_msg.name.uv = master_data_reg.total_prp_msg.bit.cuv;
    can_msg->data.half_buf[0] = alarm_msg.half_word;
    can_msg->data.half_buf[1] = warn_msg.half_word;
    can_msg->data.byte_buf[4] = master_data_reg.parallel_num;
    can_msg->data.byte_buf[5] = 0;
	can_msg->data.byte_buf[6] = 0;
    can_msg->data.byte_buf[7] = 0;
}

static void can_get_0x35C_msg(can_frame_type *can_msg)
{
	ask_cmd_type cmd_msg = {0};
    can_msg->frame_type = CAN_FRAME_DATA;
    can_msg->id_type = CAN_ID_STD;
    can_msg->dlc = 8;
    can_msg->id = 0x35C;

	cmd_msg.name.force1_chg = parallel_get_pcs_ctrl(PARALLEL_PCS_FROCE_CHG1);
	cmd_msg.name.force2_chg =  parallel_get_pcs_ctrl(PARALLEL_PCS_FROCE_CHG2);
	cmd_msg.name.chg_en = parallel_get_pcs_ctrl(PARALLEL_PCS_CHG_EN);
	cmd_msg.name.dsg_en = parallel_get_pcs_ctrl(PARALLEL_PCS_DSG_EN);
	//cmd_msg.name.full_Chg = var_get_data(VAR_ID_ASK_FULL_CHG);
    can_msg->data.byte_buf[0] = cmd_msg.byte_data;
    can_msg->data.byte_buf[1] = 0;
    can_msg->data.half_buf[1] = 0;
    can_msg->data.half_buf[2] = 0;
    can_msg->data.half_buf[3] = 0;
}

static void can_get_0x370_msg(can_frame_type *can_msg)
{   
    can_msg->frame_type = CAN_FRAME_DATA;
    can_msg->id_type = CAN_ID_STD;
    can_msg->dlc = 8;
    can_msg->id = 0x370;

    can_msg->data.half_buf[0] = var_get_data(VAR_ID_TP_MAXT_VAL) - 2731;
    can_msg->data.half_buf[1] = var_get_data(VAR_ID_TP_MINT_VAL) - 2731;
	can_msg->data.half_buf[2] = var_get_data(VAR_ID_TP_MAXC_VOLT);
    can_msg->data.half_buf[3] = var_get_data(VAR_ID_TP_MINC_VOLT);
}

static void can_get_0x371_msg(can_frame_type *can_msg)
{
    can_msg->frame_type = CAN_FRAME_DATA;
    can_msg->id_type = CAN_ID_STD;
    can_msg->dlc = 8;
    can_msg->id = 0x371;

    can_msg->data.half_buf[0] = var_get_data(VAR_ID_TP_MAXT_SN);
    can_msg->data.half_buf[1] = var_get_data(VAR_ID_TP_MINT_SN);
    can_msg->data.half_buf[2] = var_get_data(VAR_ID_TP_MAXC_SN);
    can_msg->data.half_buf[3] = var_get_data(VAR_ID_TP_MINC_SN);
}

static void can_get_0x380_msg(can_frame_type *can_msg)
{
    can_msg->frame_type = CAN_FRAME_DATA;
    can_msg->id_type = CAN_ID_STD;
    can_msg->dlc = 8;
    can_msg->id = 0x380;

    can_msg->data.half_buf[0] = 0;
    can_msg->data.half_buf[1] = 0;
    can_msg->data.half_buf[2] = 0;
    can_msg->data.half_buf[3] = 0;
}

static void can_get_0x381_msg(can_frame_type *can_msg)
{
    can_msg->frame_type = CAN_FRAME_DATA;
    can_msg->id_type = CAN_ID_STD;
    can_msg->dlc = 8;
    can_msg->id = 0x381;

    can_msg->data.half_buf[0] = 0;
    can_msg->data.half_buf[1] = 0;
    can_msg->data.half_buf[2] = 0;
    can_msg->data.half_buf[3] = 0;
}

/********** Copyright (c) 2023 JBD-Energy Storage Technology Co. LTD *********/


